//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2005
//
// 'Zoom' tool.
//

# include "StdAfx.h"
# include "Resource.h"
# include "Tool.h"
# include "PtAlgo.h"
# include "Map.h"
# include "Position.h"
# include "Scale.h"
# include "MapView.h"
# include "Globals.h"

class CZoomTool : public CTool {
  public:
	CZoomTool () : CTool (toolZoom) {}

	virtual bool Init ();
	virtual void Destroy ();

	virtual void OnActivate ();

	virtual void OnLDown (int _x, int _y, DWORD _dwKeys);
	virtual void OnLUp   (int _x, int _y, DWORD _dwKeys);
	virtual void OnMove  (int _x, int _y, DWORD _dwKeys);
	virtual void OnRDown (int _x, int _y, DWORD _dwKeys);
	virtual void OnRUp   (int _x, int _y, DWORD _dwKeys);

	virtual void OnEsc ();

	virtual void OnPaint (HDC _hDC, const RECT & _rect);
};

DECLARE_TOOL (CZoomTool);

static HCURSOR g_hcurZoom;
static HCURSOR g_hcurZoomIn;
static HCURSOR g_hcurZoomOut;
static HCURSOR g_hcurZoomDrag;

static HBRUSH g_hbrZoom;

bool CZoomTool::Init () {
	assert (g_hInst);

	g_hcurZoom     = ::LoadCursor (g_hInst, MAKEINTRESOURCE (IDC_CursorZoom));
	g_hcurZoomIn   = ::LoadCursor (g_hInst, MAKEINTRESOURCE (IDC_CursorZoomIn));
	g_hcurZoomOut  = ::LoadCursor (g_hInst, MAKEINTRESOURCE (IDC_CursorZoomOut));
	g_hcurZoomDrag = ::LoadCursor (g_hInst, MAKEINTRESOURCE (IDC_CursorZoomDrag));

	g_hbrZoom = ::CreateSolidBrush (c_colGray);

	return true;
}

void CZoomTool::Destroy () {
	if (g_hbrZoom)
		::DeleteObject (g_hbrZoom);
}

void CZoomTool::OnActivate () {
	SetPermanentCursor (g_hcurZoom);
}

void CZoomTool::OnLDown (int _x, int _y, DWORD _dwKeys) {
	SetPermanentCursor (g_hcurZoomIn);

	StartDND (_x, _y);
}

void CZoomTool::OnLUp (int _x, int _y, DWORD _dwKeys) {
	SetPermanentCursor (g_hcurZoom);
	if (CTool::s_bDND) {
		StopDND ();
		const long lDx = ::labs (_x - CTool::s_lX_DND_Start);
		const long lDy = ::labs (_y - CTool::s_lY_DND_Start);
		if (
			lDx < ::GetSystemMetrics (SM_CXDRAG) &&
			lDy < ::GetSystemMetrics (SM_CYDRAG)
		) {
			SetScale (g_fScale/c_Sqrt4, _x, _y);
		} else {
			point_t point;
			ScreenToPt ((CTool::s_lX_DND_Start + _x)/2, (CTool::s_lY_DND_Start + _y)/2, point);
			SetToCenter (point);

			const float fKx = float (lDx)/g_lWidth;
			const float fKy = float (lDy)/g_lHeight;

			SetScale (fKx > fKy ? g_fScale*fKx : g_fScale*fKy);
		}
	}
}

void CZoomTool::OnMove (int _x, int _y, DWORD _dwKeys) {
	if (
		CTool::s_bDND &&
		(
			::labs (_x - CTool::s_lX_DND_Start) >= ::GetSystemMetrics (SM_CXDRAG) ||
			::labs (_y - CTool::s_lY_DND_Start) >= ::GetSystemMetrics (SM_CYDRAG)
		)
	) {
		SetPermanentCursor (g_hcurZoomDrag);
		Redraw ();
	} else
		SetPermanentCursor (g_hcurZoom);
}

void CZoomTool::OnRDown (int _x, int _y, DWORD _dwKeys) {
	CTool::s_lX_DND_Start = _x;
	CTool::s_lY_DND_Start = _y;
	SetPermanentCursor (g_hcurZoomOut);
}

void CZoomTool::OnRUp (int _x, int _y, DWORD _dwKeys) {
	SetPermanentCursor (g_hcurZoom);
	if (
		::labs (_x - CTool::s_lX_DND_Start) >= ::GetSystemMetrics (SM_CXDRAG) ||
		::labs (_y - CTool::s_lY_DND_Start) >= ::GetSystemMetrics (SM_CYDRAG)
	)
		return;

	SetScale (g_fScale*c_Sqrt4, _x, _y);
}

void CZoomTool::OnEsc () {
	StopDND ();
	Redraw ();
}

void CZoomTool::OnPaint (HDC _hDC, const RECT & _rect) {
	if (! CTool::s_bDND)
		return;

	RECT rect;

	rect.left  = CTool::s_lX_DND_Start;
	rect.right = CTool::s_lX_DND;
	if (rect.left > rect.right)
		std::swap (rect.left, rect.right);
	++ rect.left;

	rect.top    = CTool::s_lY_DND_Start;
	rect.bottom = CTool::s_lY_DND;
	if (rect.top > rect.bottom)
		std::swap (rect.top, rect.bottom);
	++ rect.top;

	::FrameRect (_hDC, & rect, g_hbrZoom);
}